Skip to content

fix(pallet-tft-bridge): reject creating an already-executed refund#1093

Merged
sameh-farouk merged 1 commit into
developmentfrom
fix/pallet-refund-executed-guard
Jun 1, 2026
Merged

fix(pallet-tft-bridge): reject creating an already-executed refund#1093
sameh-farouk merged 1 commit into
developmentfrom
fix/pallet-refund-executed-guard

Conversation

@sameh-farouk
Copy link
Copy Markdown
Member

Problem

create_stellar_refund_transaction_or_add_sig only checked whether the refund existed in RefundTransactions, not whether it had already been executed. A refund that was already executed — e.g. quarantined by the bridge after a permanently undeliverable Stellar submission (see #1089 / companion bridge PR) — could be silently recreated, re-arming the on_finalize retry loop.

This is also a consistency gap: the mint and burn paths already guard against re-creating an executed transaction; the refund path was the lone exception.

  • propose_or_vote_stellar_mint_transaction → checks ExecutedMintTransactions
  • propose_stellar_burn_transaction_or_add_sig → checks ExecutedBurnTransactions
  • create_stellar_refund_transaction_or_add_sigchecked neither (only RefundTransactions::contains_key)

Fix

Add an ExecutedRefundTransactions guard, returning RefundTransactionAlreadyExecuted, mirroring the mint/burn checks.

The bridge already recovers from this error gracefully: RetryCreateRefundTransactionOrAddSig re-checks IsRefundedAlready after a failed create and exits cleanly, so no bridge change is required.

Scope notes

  • No spec_version bump. Per docs/production/releases.md, version/spec bumps are a release-time step (make version-bump). This PR is a runtime logic change and requires a runtime upgrade at release.
  • No storage migration: the guard reads an existing storage map; no layout change.
  • No new events/extrinsics; transaction_version unchanged.

Tests

TDD: added creating_refund_for_already_executed_transaction_fails (watched it fail — re-creation returned Ok instead of the error — then added the guard). Full pallet suite: 19 passed.

Refs #1089

🤖 Generated with Claude Code

@sameh-farouk sameh-farouk requested a review from LeeSmet as a code owner June 1, 2026 14:57
create_stellar_refund_transaction_or_add_sig only checked whether the
refund existed in RefundTransactions, not whether it had already been
executed. A refund that was already executed (e.g. quarantined by the
bridge after a permanently undeliverable Stellar submission) could be
silently recreated, re-arming the on_finalize retry loop.

Add an ExecutedRefundTransactions guard, mirroring the existing checks in
propose_or_vote_stellar_mint_transaction and
propose_stellar_burn_transaction_or_add_sig. The bridge already recovers
from the resulting RefundTransactionAlreadyExecuted error via the
IsRefundedAlready check in RetryCreateRefundTransactionOrAddSig.

Note: spec_version is intentionally not bumped here; that is handled at
release time via `make version-bump` (see docs/production/releases.md).

Refs #1089

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant